#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@File   : SystemApi.py
@Time : 2025/1/3 10:51
@Author: Wangwc
@Describe:  登录&桌面相关业务方法封装
"""
import requests

from utils.encrypt_tools import DataEncrypt
from utils.requests_tools import HttpRequest, check_response, retry_func
from commons.logger import log
from utils.config_tools import Config

# TODO 当前模块的配置文件名称，配置在config目录下
config_name = 'cloud.ini'

assert_message = {'code': 200, 'msg': 'success'}


class LoginApi:

    def __init__(self, user="user", config_name="cloud.ini"):
        self.user = user
        self.config_name = config_name

        """
                :param user: cloud.ini配置文件中user节点的用户名,默认为user,也可以传入其他节点的用户名
                """
        self.hostname = Config(self.config_name).read_config_ini('envHost', 'hostname')
        self.username = Config(self.config_name).read_config_ini(self.user, 'user_name')
        self.raw_password = Config(self.config_name).read_config_ini(self.user, 'user_pwd')
        self.data_encrypt = DataEncrypt()  # 实例化DataEncrypt对象，方便后续复用
        self.http = HttpRequest(self.config_name)  # 实例化HttpRequest对象，方便后续复用

    def _is_request_successful(self, response):
        """
        判断请求是否成功（状态码在200 - 299区间）
        :param response: requests库的响应对象
        :return: 布尔值，表示请求是否成功
        """
        return 200 <= response.status_code < 300

    @check_response('查找局域网设备接口', ext='data.deviceMatchs', check={'code': 200, 'msg': '成功'})
    def get_devices(self):
        """
        获取当前局域网内设备信息
        :return: 当前局域网内设备列表
        """
        log.debug("开始获取当前局域网内设备信息")
        path = "https://api-test1.ugnas.com/api/device/v1/ua/network/match"
        try:
            response = self.http.post(path)
            return response
        except Exception as e:
            log.error(f"在获取当前局域网内设备信息过程中出现异常，异常信息: {e}")
            raise

    def get_device(self, sn, devices: list):
        """
        检查设备是否在线
        :param devices: 当前局域网内设备列表信息
        :return:  设备信息
        """
        log.info(f"开始检查设备 {sn} 是否在线，传入的设备列表包含 {len(devices)} 个设备")
        try:
            for index, device in enumerate(devices):
                log.debug(f"正在检查第 {index + 1} 个设备，设备信息为: {device}")
                if device.get('deviceSn') == sn:
                    log.info(f"在设备列表中找到设备 {sn}，设备在线")
                    device_info = device
                    return device_info
                else:
                    log.debug(f"第 {index + 1} 个设备 {device.get('deviceSn', '未知设备号')} 不是目标设备 {sn}")
            else:
                log.info(f"遍历完所有设备，未找到设备 {sn}，设备不在线")
                return None
        except Exception as e:
            log.error(f"在检查设备是否在线过程中出现异常，异常信息: {str(e)}，设备列表信息为: {devices}")

    def general_verify_check(self, hostname, protocol='http', port=9999,username=None):
        """
        获取公钥接口
        :param protocol : 协议类型，例如http或https
        hostname : 主机名  172.17.20.57,
        port : 端口号  9999、9443
        """
        path = f'{protocol}://{hostname}:{port}/ugreen/v1/verify/check'
        username = username if username is not None else self.username
        data = {"username": username}
        try:
            log.info(f"请求路径为{path},请求参数为{data}")
            result = self.http.post(path, json=data)
            return result.headers.get('X-Rsa-Token') if self._is_request_successful(result) else None
        except requests.ConnectionError as e:
            log.error(f"网络连接出现问题，获取公钥请求失败: {e}")
            raise  # 可以选择抛出，或者根据需要返回合适的值并记录日志，这里选择抛出以便上层处理
        except requests.Timeout as e:
            log.error(f"获取公钥请求超时: {e}")
            raise
        except Exception as e:
            log.error(f"获取公钥接口出现其他异常: {e}")
            raise

    @check_response('登录接口',ext="data")
    def general_login(self, hostname,Rsa_Token, protocol='http', port=9999, username=None, raw_password=None):
        """
        重新封装一个登录方法，默认根据选择config.ini里面的user账号登录，也支持输入用户账号、密码
        :param hostname: 主机名
        :param protocol: 协议类型，默认为http
        :param port: 端口号，默认为9999
        :param username: 登录用户名，可选，若不传则使用配置文件中的默认用户名
        :param raw_password: 登录密码，可选，若不传则使用配置文件中的默认密码
        :return: 登录成功返回获取到的token，失败返回None，并记录相应的错误日志信息
        """
        login_path = f'{protocol}://{hostname}:{port}/ugreen/v1/verify/login'
        if Rsa_Token is None:
            log.error("获取公钥失败，无法进行登录操作")
            return None

        # 获取用户名和密码，优先使用传入参数，若不传则使用配置文件中的默认值
        username = username if username is not None else self.username
        raw_password = raw_password if raw_password is not None else self.raw_password

        try:
            encrypted_passwd = self.data_encrypt.rsa_passwd(Rsa_Token, raw_password)
            data_login = {
                "username": username,
                "password": encrypted_passwd,
            }
            # 记录请求相关信息，方便调试排查问题（使用DEBUG级别日志，可根据需要调整级别）
            log.debug(f"发起登录请求，URL: {login_path}，请求体: {data_login}")
            response = self.http.post(login_path, json=data_login)
            return response
        except requests.ConnectionError as e:
            # 返回更具体的错误提示信息给调用者
            error_msg = f"网络连接出现问题，登录过程出现异常，请检查网络连接: {e}"
            log.error(error_msg)
            return error_msg
        except requests.Timeout as e:
            # 返回更具体的错误提示信息给调用者
            error_msg = f"登录请求超时，请检查网络状况或调整超时设置: {e}"
            log.error(error_msg)
            return error_msg
        except Exception as e:
            log.error(f"登录过程出现其他异常: {e}")
            return None



if __name__ == "__main__":
    # hostname = '172.17.20.57'
    login = LoginApi()
    # Rsa_token = login.general_verify_check(hostname)
    # result = login.general_login(hostname,Rsa_token,raw_password='Aa123456@')
    devices = login.get_devices()
    device = login.get_device('U43001M53V8C0966',devices)
    print(device)
    # result = login.check_device(devices)
    # print(result)
